package com.rpc.handler;

import com.google.protobuf.ByteString;
import com.netty.client.socket.ImSocketClient;
import com.netty.client.socket.ImSocketClientHandler;
import com.netty.constant.Constants;
import com.netty.model.proto.MessageBodyProto;
import com.rpc.common.ChannelMaps;
import com.rpc.common.Invocation;
import com.rpc.config.RpcServiceConfig;
import com.rpc.invoke.RpcInvoke;
import com.rpc.utils.ProtostuffUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

public class RpcServiceHandler implements ImSocketClientHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ImSocketClient imSocketClient = null;
    private String serverName = "";
    public void startServer(String url, int port,String serverName){
        this.serverName = serverName;
        imSocketClient = new ImSocketClient(url,port,this);
        imSocketClient.startClient();
    }
    public void startServer(String url, int port){
        imSocketClient = new ImSocketClient(url,port,this);
        imSocketClient.startClient();
    }

    @Override
    public void channelActive(ChannelHandlerContext channelHandlerContext) {
        MessageBodyProto.Model.Builder body = MessageBodyProto.Model.newBuilder();
        body.setType(Constants.CmdType.ONLINE);
        body.setTimestamp(new Date().getTime());
        body.setKey(serverName+"server-"+ UUID.randomUUID().toString().replaceAll("-",""));
        body.putData("channel", ByteString.copyFrom(Constants.ImserverConfig.SOCKET.getBytes()));
        channelHandlerContext.writeAndFlush(body);
    }

    @Override
    public void channelRead0(Channel channel, MessageBodyProto.Model model) {
        if (model instanceof MessageBodyProto.Model) {
            String requestId = model.getDataMap().get("requestId").toStringUtf8();
            String time = model.getDataMap().get("time").toStringUtf8();
            if(Objects.isNull(requestId)) return;
            logger.info("获取请求id【{}】",requestId);
            Invocation invocation = (Invocation) ProtostuffUtils.deserialize(model.getDataMap().get("invocation").toByteArray());
            RpcServiceConfig aClass = ChannelMaps.getRpcServiceConfig(invocation);
            RpcInvoke rpcInvoke = new RpcInvoke();
            Object result = rpcInvoke.invoke(aClass.getService().getClass(),invocation);
            MessageBodyProto.Model.Builder builder = MessageBodyProto.Model.newBuilder();
            builder.setKey(model.getKey());
            builder.setType(Constants.CmdType.MESSAGE);
            builder.putData("requestId",ByteString.copyFrom(requestId.getBytes(StandardCharsets.UTF_8)));
            builder.putData("time",ByteString.copyFrom(time.getBytes(StandardCharsets.UTF_8)));
            builder.putData("data",ByteString.copyFrom(ProtostuffUtils.serialize(result)));
            logger.info("请求执行完成【{}】",requestId);
            channel.writeAndFlush(builder);
        }

    }

    @Override
    public void channelUnregistered(ChannelHandlerContext channelHandlerContext) {
    }
}
